﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Lant.Net.Model;

namespace Lant.Net.Game
{
	public partial class Dragon : Puke, IDisposable
	{
		private readonly int CARDCOUNT = 6;
		private const string _GameName = "变色龙 v1.0";
		private const string _GameRule = "先不告诉你";

		private Puker puker;
		private PukeInfo pukeInfo;
		private List<PukeCard> my = null, he = null, publicCard = null, myCard = null, heCard = null;

		public PukeInfo PukeInfo { get { return pukeInfo; } }
		Button btnSend;
		Button btnGet;
		Label lblMessage;
		private int heSign = -1;
		private int heNumber = -1;
		private int NumberCount = 1;
		private bool isFirst = true;
		private bool isHeOver = false;
		private string state = "";
		private int ReplaceSign = -1;
		private int ChangeSign = -1;

		#region  构造函数
		public Dragon()
		{
			InitializeComponent();
			pukeInfo = new PukeInfo30x40();
			puker = new Puker(pukeInfo, PukerMode.puke54);
			btnSend = new Button();
			btnSend.Top = 150;
			btnSend.Left = 135;
			btnSend.Width = 40;
			btnSend.Text = "出牌";
			btnSend.Click += new EventHandler(btnSend_Click);
			btnGet = new Button();
			btnGet.Top = 150;
			btnGet.Left = 180;
			btnGet.Width = 40;
			btnGet.Text = "过";
			btnGet.Click += new EventHandler(btnGet_Click);
			lblMessage = new Label();
			lblMessage.Top = 60;
			lblMessage.Left = 10;
			lblMessage.Width = 220;
		}
		#endregion

		#region 覆写属性和方法
		public override string GameName { get { return _GameName; } }
		public override string GameRule { get { return _GameRule; } }
		public override bool Start()
		{
			//MessageBox.Show("0");
			puker.Start();
			my = puker.GetPukeCard(this.CARDCOUNT);
			he = puker.GetPukeCard(this.CARDCOUNT);
			publicCard = new List<PukeCard>();
			myCard = new List<PukeCard>();
			heCard = new List<PukeCard>();
			this.btnSend.Enabled = true;
			this.lblMessage.Text = "游戏开始，请出牌..";
			heSign = -1;
			heNumber = -1;
			isFirst = true;
			this.UpdateForm();
			return true;
		}
		#endregion

		#region 事件
		private void btnSend_Click(object sender, EventArgs e)
		{
			if (!this.btnSend.Enabled) return;
			bool heisStart = false;
			int tempCount = 0;
			this.ReplaceSign = -1;
			List<PukeCard> mySelect = this.GetSelected(my);
			if (mySelect.Count < 1)
				return;
			if (isFirst || isHeOver || mySelect[0].Sign == 4 || mySelect[0].Number == heNumber || mySelect[0].Sign == heSign && mySelect.Count == NumberCount)
			{
				if (mySelect[0].Number == heNumber)
				{
					for (int i = 0; i < my.Count; i++)
					{
						if (my[i].Sign == heSign)
						{
							this.lblMessage.Text = "你还有[" + pukeInfo.GetCardSignDisplay(heSign) + "]，不能变牌";
							return;
						}
					}
				}
				else if (ChangeSign == -1 && mySelect[0].Sign == 4)
				{
					this.lblMessage.Text = "选择花色";
					this.btnSend.Enabled = false;
					this.btnGet.Enabled = false;
					this.SelectSign();
					return;
				}
				else if (ChangeSign != -1 && mySelect[0].Sign == 4)
				{
					this.lblMessage.Text = "我[鬼牌]选择了" + pukeInfo.GetCardSignDisplay(heSign);
					ReplaceSign = heSign;
					//mySelect[0].Number = 99;
					ChangeSign = -1;
				}
				isFirst = false;
				PukeCard[] ps = new PukeCard[my.Count];
				my.CopyTo(ps);
				for (int i = 0; i < ps.Length; i++)
				{
					if (ps[i].Selected)
					{
						tempCount += 1;
						if (tempCount > NumberCount) break;
						publicCard.Add(ps[i]);
						my.Remove(ps[i]);
						this.lblMessage.Text = "我出了[" + pukeInfo.GetCardSignDisplay(ps[i].Sign) + "]";
					}
				}
				heisStart = this.heStart(mySelect[0]);
			}
			else
			{
				//this.lblMessage.Text = string.Format("牌不对，上家出了 {0} 张[{1}]，你选择了[{2}]。", NumberCount, pukeInfo.GetCardSignDisplay(heSign), pukeInfo.GetCardSignDisplay(mySelect[0].Sign));
				MessageBox.Show(string.Format("牌不对，上家出了 {0} 张[{1}]，你选择了[{2}]。", NumberCount, pukeInfo.GetCardSignDisplay(heSign), pukeInfo.GetCardSignDisplay(mySelect[0].Sign)), "提示");
			}
			this.UpdateForm();
			if (my.Count == 0 && !heisStart)
				this.gameOver("my");
		}

		private void btnGet_Click(object sender, EventArgs e)
		{
			publicCard.Clear();

			if (state == "get")
			{//他没牌了，我取牌
				btnSend.Enabled = true;
				state = "";
				btnGet.Text = "过";
				heSign = -1;
				if (he.Count != 0)
				{
					he.Sort(PukeCardCompare.NumberDesc);
					heCard.Add(he[he.Count - 1]);
					he.RemoveAt(he.Count - 1);
				}
				my.AddRange(puker.GetPukeCard(this.CARDCOUNT - my.Count));
				he.AddRange(puker.GetPukeCard(this.CARDCOUNT - he.Count));
				this.lblMessage.Text = "请出牌..";
			}
			else
			{//我点pass
				//heRecord.AddRange(temp);
				this.lblMessage.Text = "您被扣分了，请选择一张牌";
				this.btnSend.Enabled = false;
				this.btnGet.Enabled = false;
				this.SelectCard();
				return;

			}
			//MessageBox.Show(string.Format("my = {0},he = {1}", myCard.Count.ToString(), heCard.Count.ToString()));
			this.UpdateForm();
		}

		void btnSelect_Click(object sender, EventArgs e)
		{
			PukeCard p = null;
			int tempI = 0;
			for (int i = 0; i < my.Count; i++)
				if (my[i].Selected)
				{
					p = my[i];
					tempI++;
				}
			if (tempI > 1 || (my.Count != 0 && tempI == 0))
			{
				this.lblMessage.Text = "请选择一张牌";
				//MessageBox.Show("请选择一张牌", "提示");
				return;
			}
			if (p != null)
			{
				myCard.Add(p);
				my.Remove(p);
			}
			he.AddRange(puker.GetPukeCard(this.CARDCOUNT - he.Count));
			my.AddRange(puker.GetPukeCard(this.CARDCOUNT - my.Count));
			this.heStart(null);
			this.btnSend.Enabled = true;
			this.btnGet.Enabled = true;
			this.UpdateForm();
		}
		private void btnSelectSign_Click(object sender, EventArgs e)
		{
			heSign = (int)((Button)sender).Tag;
			ChangeSign = heSign;
			this.btnSend.Enabled = true;
			this.btnGet.Enabled = true;
			this.btnSend_Click(sender, e);
		}
		#endregion

		#region 私有方法
		private void SelectCard()
		{
			Button btnSelect = new Button();
			btnSelect.Top = 150;
			btnSelect.Left = 10;
			btnSelect.Width = 40;
			btnSelect.Text = "选择";
			btnSelect.Click += new EventHandler(btnSelect_Click);
			this.Controls.Add(btnSelect);
		}

		private void SelectSign()
		{
			for (int i = 0; i < 4; i++)
			{
				Button btnSign = new Button();
				btnSign.Text = pukeInfo.GetCardSignDisplay(i).Substring(0, 1);
				btnSign.Tag = i;
				btnSign.Top = 150;
				btnSign.Left = 10 + (3 - i) * 25;
				btnSign.Width = 20;
				btnSign.Click += new EventHandler(btnSelectSign_Click);
				this.Controls.Add(btnSign);
			}
		}

		private void gameOver(string m)
		{
			int heCount = 0, myCount = 0;
			string mResult = "";
			for (int i = 0; i < heCard.Count; i++)
			{
				heCount += heCard[i].Number;
			}
			for (int i = 0; i < myCard.Count; i++)
			{
				myCount += myCard[i].Number;
			}
			if (myCount < heCount)
				mResult = "你胜利了";
			else if (myCount > heCount)
				mResult = "你失败了";
			else
				mResult = "你们旗鼓相当";
			this.lblMessage.Text = "游戏结束，" + mResult;
			if (MessageBox.Show(string.Format("游戏结束，{0}！！\r\n\r\n她得了 {1}分\r\n我得了 {2}分\r\n\r\n要重新开始吗？", mResult, heCount, myCount), "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
			{
				this.Start();
			}
		}

		private bool heStart(PukeCard myCard)
		{
			isHeOver = false;
			if (myCard == null)
			{
				if (he.Count == 0) { this.UpdateForm(); this.gameOver("he"); return false; }
				Random random = new Random();
				PukeCard temp = he[random.Next(he.Count)];
				if (temp.Sign == 4)
				{
					heSign = random.Next(4);
					this.lblMessage.Text = "她出了[" + pukeInfo.GetCardSignDisplay(temp.Sign) + pukeInfo.GetCardNumberDisplay(temp.Number) + "]，她选择[" + pukeInfo.GetCardSignDisplay(heSign) + "]";
					//MessageBox.Show(pukeInfo.GetCardSignDisplay(heSign));
				}
				else
				{
					this.lblMessage.Text = "她出了[" + pukeInfo.GetCardSignDisplay(temp.Sign) + pukeInfo.GetCardNumberDisplay(temp.Number) + "]";
					heSign = temp.Sign;
					heNumber = temp.Number;
				}
				publicCard.Add(temp);
				he.Remove(temp);
			}
			else
			{
				//MessageBox.Show(tempSign.ToString());
				he.Sort(PukeCardCompare.NumberDesc);
				PukeCard heCard = null;
				PukeCard[] ps = new PukeCard[he.Count];
				he.CopyTo(ps);
				int tempCount = 0;
				int tempSign = -1;
				if (ReplaceSign == -1)
					tempSign = myCard.Sign;
				else
					tempSign = ReplaceSign;
				//MessageBox.Show(tempSign.ToString());
				PukeCard tempKing = null;
				//int OtherNumberSign = -1;
				//System.Collections.Hashtable hash = new System.Collections.Hashtable();
				PukeCard tempOtherCard = null;
				foreach (PukeCard p in ps)
				{
					if (p.Sign == tempSign)
					{
						tempCount += 1;
						if (tempCount <= NumberCount)
						{
							heCard = p;
							heSign = tempSign;
							heNumber = p.Number;
							publicCard.Add(p);
							he.Remove(p);
						}
					}
					if (p.Sign == 4)
						tempKing = p;
					if (p.Number == myCard.Number && p.Sign != 4)
						tempOtherCard = p;
				}
				if (tempCount < NumberCount)
				{
					if (tempOtherCard != null)
					{
						//PukeCar.d temp = this.GetPolicy(hash);
						heSign = tempOtherCard.Sign;
						heNumber = tempOtherCard.Number;
						publicCard.Add(tempOtherCard);
						he.Remove(tempOtherCard);
						this.lblMessage.Text = "我出了[" + pukeInfo.GetCardSignDisplay(myCard.Sign) + pukeInfo.GetCardNumberDisplay(myCard.Number) + "],她[变牌]出了[" + pukeInfo.GetCardSignDisplay(heSign) + pukeInfo.GetCardNumberDisplay(tempOtherCard.Number) + "]";
					}
					else if (tempKing != null)
					{
						heSign = tempKing.Sign;
						heNumber = tempKing.Number;
						publicCard.Add(tempKing);
						he.Remove(tempKing);
						this.lblMessage.Text = "我出了[" + pukeInfo.GetCardSignDisplay(myCard.Sign) + pukeInfo.GetCardNumberDisplay(myCard.Number) + "],她[变牌]出了[" + pukeInfo.GetCardSignDisplay(heSign) + pukeInfo.GetCardNumberDisplay(heCard.Number) + "]";
					}
					else
					{
						isHeOver = true;
						//this.lblMessage.Text = "oh,no [" + pukeInfo.GetCardSignDisplay(tempSign) + "]";
						heSign = -1;
						heNumber = -1;
						this.lblMessage.Text = "[" + pukeInfo.GetCardSignDisplay(tempSign) + "]结束，点击[取牌]获得更多的牌";
						btnSend.Enabled = false;
						btnGet.Enabled = true;
						btnGet.Text = "取牌";
						state = "get";
						return false;
					}
				}
				else
				{
					this.lblMessage.Text = "我出了[" + pukeInfo.GetCardSignDisplay(myCard.Sign) + pukeInfo.GetCardNumberDisplay(myCard.Number) + "],她出了[" + pukeInfo.GetCardSignDisplay(heSign) + pukeInfo.GetCardNumberDisplay(heCard.Number) + "]";
					//this.lblMessage.Text = "";
				}
			}

			if (my.Count == 0)
			{
				this.state = "";
				this.btnGet_Click(null, null);
			}
			if (he.Count == 0)
				this.gameOver("he");
			return true;
		}
		private void UpdateForm()
		{
			this.Controls.Clear();
			this.Controls.Add(lblMessage);
			this.Controls.Add(btnSend);
			this.Controls.Add(btnGet);
			my.Sort(PukeCardCompare.SignAsc);
			for (int i = my.Count - 1; i >= 0; i--)
			{
				if (my[i].DoubleClickEventHandler == null)
					my[i].DoubleClickEventHandler = new EventHandler(this.btnSend_Click);
				my[i].Top = 190;
				my[i].Left = i * pukeInfo.OffsetX + 10;
				my[i].Clicked = true;
				my[i].Display = true;
				if (my[i].Selected)
					my[i].Top -= my[i].TopOffSet;
				this.Controls.Add(my[i]);
			}
			for (int i = myCard.Count - 1; i >= 0; i--)
			{
				myCard[i].Top = 190;
				myCard[i].Left = i * 2 + 160;
				myCard[i].Clicked = false;
				myCard[i].Display = true;
				this.Controls.Add(myCard[i]);
			}

			for (int i = publicCard.Count - 1; i >= 0; i--)
			{
				publicCard[i].Top = 100;
				publicCard[i].Left = i * pukeInfo.OffsetX + 10;
				publicCard[i].Clicked = false;
				publicCard[i].Display = true;
				this.Controls.Add(publicCard[i]);
			}

			he.Sort(PukeCardCompare.SignDesc);
			for (int i = he.Count - 1; i >= 0; i--)
			{
				he[i].Top = 5;
				he[i].Left = i * pukeInfo.OffsetX + 10;
				he[i].Clicked = false;
				he[i].Display = false;
				this.Controls.Add(he[i]);
			}
			for (int i = heCard.Count - 1; i >= 0; i--)
			{
				heCard[i].Top = 5;
				heCard[i].Left = i * 2 + 160;
				heCard[i].Clicked = false;
				heCard[i].Display = true;
				this.Controls.Add(heCard[i]);
			}
		}
		#endregion

		#region IDisposable 成员

		void IDisposable.Dispose()
		{
			he.Clear();
			my.Clear();
			publicCard.Clear();
			heCard.Clear();
			myCard.Clear();
			System.GC.Collect();
		}

		#endregion
	}
}
